{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "629c2685",
   "metadata": {},
   "source": [
    "* 学习人：铭晶\n",
    "* 时间：2021-12-02\n",
    "* week 14"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76b621b5",
   "metadata": {},
   "source": [
    "# 函数\n",
    "## 1.函数的定义\n",
    ">1.数学：f(x)=ax+b     \n",
    ">2.python: def fib(x):     \n",
    ">3.编程思维 vs 数学思维  \n",
    ">>1.函数可以被定义名称，定义的关键字 <font style=\"color:red\">**def**</font>   \n",
    ">>2.数学思维是写在同一行（定义函数和运算公式），面向对象编程中函数写多行，定义函数为单独一行    \n",
    ">>3.数学函数一般没有注释，而编程过程中，一般需要对函数进行注释描述（docstring,课表p151）   \n",
    ">>4.数学中：ax+b是计算公式，而编程中，我们将函数的内容成为**函数体**，函数体要有一定的**缩进**    \n",
    ">>5.数学函数执行，将参数代入公式，编程中函数执行，将参数代入函数体    \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## 2.函数的进阶"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b4885a8",
   "metadata": {},
   "source": [
    "* 定义函数\n",
    "def:定义函数的关键字    \n",
    "fib：函数名     \n",
    "(n)：定义函数的参数    \n",
    "\"\"\"\"\"\"：文档描述     \n",
    "代码块：\n",
    "     a, b = 0, 1\n",
    "     while a < n:\n",
    "        print(a, end=' ')\n",
    "         a, b = b, a+b\n",
    "     print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "2a706dbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 菲波那切数列： 0 1 1 2 3 5 8 13 21 34 ...\n",
    "def fib(x):\n",
    "    \"\"\"列出指定x以内的菲波那切数列\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < x:\n",
    "        print(a,end=\" \")\n",
    "        a,b=b, a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "82900347",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 "
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "b66c378b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实践：写一个函数，可以打印“你好，XXX同学~”\n",
    "def hello(name):\n",
    "    \"\"\"显示问候语\"\"\"\n",
    "    print(\"你好,%s同学~\"%(name))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "ac817be6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好,aaa同学~\n"
     ]
    }
   ],
   "source": [
    "hello(\"aaa\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "7378bbe2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好,同学~\n"
     ]
    }
   ],
   "source": [
    "hello(\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "c09c1d29",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 回顾与思考\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "d4a95e98",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# sleep ()需要给定一个时间（int）函数\n",
    "time.sleep(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "9a511766",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=12, tm_mday=2, tm_hour=11, tm_min=22, tm_sec=13, tm_wday=3, tm_yday=336, tm_isdst=0)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# localtime()不需要给定参数\n",
    "time.localtime()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5de6b91a",
   "metadata": {},
   "source": [
    "* 函数的优势\n",
    ">1.可以重复使用相同的功能，避免重复造轮子   \n",
    ">2.使用者可以不了解函数本身，只需要清楚如何使用即可    \n",
    ">3.使用/调用方便，只需要清楚的传达函数名"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf280dc0",
   "metadata": {},
   "source": [
    "## 函数的参数\n",
    ">1.形式参数（形参）    \n",
    ">>1.在**定义**函数的时候定义的函数   \n",
    ">>2.形式参数不占内存         \n",
    "\n",
    ">2.实际参数（实参）     \n",
    ">>1.在**调用**函数的时候传递的参数   \n",
    ">>2.调用函数时，形式参数分配空间，传递实际参数，执行函数内容\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "8954a17a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 课本函数实践案例：\n",
    "def search4vowels(word):\n",
    "    \"\"\"显示文本中出现的元音字母有哪些\"\"\"\n",
    "    vowels=set(\"aeiou\")\n",
    "    word=set(word)\n",
    "    print(vowels&word)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4811f947",
   "metadata": {},
   "source": [
    "* 形式参数：Word\n",
    "* 实际参数：\"fbnjdsadekwsdsdfcvjdsuax\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "7234c91b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e', 'a', 'u'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"fbnjdsadekwsdsdfcvjdsuax\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "195c8a6d",
   "metadata": {},
   "source": [
    ">1.位置参数    \n",
    ">>1.在形式参数的定义中，有一定的先后顺序    \n",
    ">>2.在调用函数时，要考虑形参的先后顺序   \n",
    ">>3.在调用函数时，不仅要考虑参数的位置，还需要考虑形式参数的个数\n",
    "\n",
    ">2.关键字参数   \n",
    ">>1.在调用函数时，关键字函数可以不考虑形式参数的位置\n",
    "\n",
    ">3.默认参数  \n",
    ">>1.在调用函数时，可以省略传达参数    \n",
    ">>2.在调用函数时，"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "c7fb128a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(pet_name,animal_type):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a \"+ animal_type +\".\")\n",
    "    print(\"My \"+ animal_type +\"'s name is \"+pet_name.title()+\".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "20333d7d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is Bb.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"bb\",\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "8cfe0a4d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is Bb.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(animal_type=\"dog\",pet_name=\"bb\")# 不用考虑位置问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c037d4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 默认参数\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a \"+ animal_type +\".\")\n",
    "    print(\"My \"+ animal_type +\"'s name is \"+pet_name.title()+\".\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b45c1d3e",
   "metadata": {},
   "source": [
    "------------- \n",
    "* 参数注意事项\n",
    ">1.位置参数和关键字参数同时使用  \n",
    ">>1.positional argument follows keyword argument（关键字参数<font style=\"color:red\">**def**</font> 应该放在位置参数之后）  \n",
    ">>2.只要满足1的条件，剩余的关键字参数（多个）不考虑先后顺序  \n",
    "\n",
    ">2.非默认参数和默认参数同时使用（定义函数）  \n",
    ">>1.non-default argument follows default argument（默认参数<font style=\"color:red\">**def**</font>应该放在）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "dc13daca",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x,y,z):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "87d2704b",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-76-0d3bd7e3ec53>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-76-0d3bd7e3ec53>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    test(5,y=3,2)\u001b[0m\n\u001b[1;37m               ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "# 实践1\n",
    "test(5,y=3,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "3b966035",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "3\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 实践2\n",
    "test(5,3,z=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "15663c91",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "# 实践3\n",
    "test(5,z=3,y=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3dbffe0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
